package dimension.starry.player;

import dimension.starry.constants.PlayerDataType;
import dimension.starry.dataManager.PlayerDataManager;
import dimension.starry.utils.RandomUtil;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.attribute.EntityAttributes;
import net.minecraft.entity.mob.HostileEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.sound.SoundEvents;
import net.minecraft.world.World;

import static dimension.starry.constants.ExpLevel.needExp;

public class LevelUpper {

    public static void onKilling(World world, Entity entity, Entity killedEntity) {
        long expAdded = 100 + RandomUtil.randomInt(-10, 10);
        if (entity instanceof ServerPlayerEntity player) {
            if (killedEntity instanceof HostileEntity) {
                calculateAndUpdateLevel(expAdded, player);
            }
        }
    }

    private static void calculateAndUpdateLevel(long expAdded, ServerPlayerEntity player) {
        long exp = PlayerDataManager.getLong(player, PlayerDataType.EXP);
        int level = PlayerDataManager.getInt(player, PlayerDataType.LEVEL);
        int attributePoints = PlayerDataManager.getInt(player, PlayerDataType.ATTRBUTE_POINTS);
        long maxExp = needExp[level];

        if (exp + expAdded < maxExp) {
            PlayerDataManager.setServerPlayerData(player, PlayerDataType.EXP, exp + expAdded);
        } else {
            player.getServerWorld()
                .playSound(null, player.getBlockX(), player.getBlockY(), player.getBlockZ(),
                    SoundEvents.ENTITY_PLAYER_LEVELUP, player.getSoundCategory(), 1.0F, 1.0F
                );
            PlayerDataManager.setServerPlayerData(player, PlayerDataType.MAX_MAGIC, 1000 + 200L * level);
            PlayerDataManager.setServerPlayerData(player, PlayerDataType.EXP, exp + expAdded - maxExp);
            PlayerDataManager.setServerPlayerData(player, PlayerDataType.LEVEL, level + 1);
            PlayerDataManager.setServerPlayerData(player, PlayerDataType.ATTRBUTE_POINTS, attributePoints + 1);

            double maxHealth = ComputedPlayerInfo.getMaxHealth(player);
            player.getAttributes().getCustomInstance(EntityAttributes.GENERIC_MAX_HEALTH).setBaseValue(maxHealth);
        }
    }

    public static void onPlayerRespawn(ServerPlayerEntity oldPlayer, ServerPlayerEntity newPlayer, boolean alive) {
        double maxHealth = ComputedPlayerInfo.getMaxHealth(newPlayer);
        newPlayer.getAttributes().getCustomInstance(EntityAttributes.GENERIC_MAX_HEALTH).setBaseValue(maxHealth);
    }

    public static void onPlayerEquipmentChange(
        LivingEntity livingEntity, EquipmentSlot equipmentSlot, ItemStack previousStack, ItemStack currentStack
    ) {
        if (livingEntity instanceof ServerPlayerEntity serverPlayer) {
            double maxHealth = ComputedPlayerInfo.getMaxHealth(serverPlayer);
            serverPlayer.getAttributes().getCustomInstance(EntityAttributes.GENERIC_MAX_HEALTH).setBaseValue(maxHealth);
        }
    }

}
